home *** CD-ROM | disk | FTP | other *** search
-
- /* IBM bios screen control package
- Copyright Dave Newman 1991
- Permission to use these routines for any reason
- is granted as long as this copyright notice is
- included.
- This should compile on any DOS C compiler
- that supports int86() */
-
- /* declarations for these functions */
- #include <bios.h>
- /* needed for REGS union */
- #include <dos.h>
-
-
- /* these variables are global */
- /* these vars hold information about the system.
- They are valid after the call to bios_open().
- If the information in them is not relevant,
- the call to bios_open() is not necessary. */
- int cur_mode; /* current display mode */
- int cur_page; /* current display page */
- int num_cols; /* number of cols on screen */
-
- /* adapter types */
- char cga, /* color graphics adapter */
- ega, /* Enhanced graphics adapter */
- vga, /* video graphics array */
- mcga, /* PS/2 mcga display */
- mono, /* just black and white */
- herc, /* hercules graphics adapter */
- none; /* no monitor at all */
-
- char color, /* is using a color monitor */
- b_w; /* or black+white? */
-
- /* these vars hold info about the cursor position
- and the current color/attribute being used.
- (no bios_open call necessary) */
-
- /* display attribute (use to change colors) */
- unsigned char cur_attr;
- int cur_row; /* current row of cursor */
- int cur_col; /* current column of cursor */
- /* end global values */
-
- /* bios open function.
- Set up the initial values in all of the variables
- above. */
- void bios_open()
- {
- union REGS regs;
- void vtest(void);
-
- /* determine the current display mode */
- regs.x.ax = 0x0f00;
- int86(0x10,®s,®s);
- cur_mode = regs.h.al;
- cur_page = regs.h.bh;
- num_cols = regs.h.ah;
-
- /* determine the type of display in the system
- and set it's type value to 1
- on return the proper video adapter variable
- will be set as will the color or b_w value */
- none=mono=herc=cga=ega=vga=mcga=color=b_w=0;
- vtest();
- }
-
- /* and a bios_close function just for the sake of
- consistency. Please use this function. It may do
- something one day (like restore the screen
- to the previous state) */
- void bios_close()
- {}
-
- /* change value of cursor.
- range 0x0000 to 0xFFFF (FFFF == OFF) */
- void bios_cursor(int state)
- {
- union REGS regs;
- regs.h.ah = 1;
- /* ch == start line. cl == end line */
- regs.x.cx = state;
- int86(0x10,®s,®s);
- }
-
- /* move cursor to row,col */
- void bios_move(int row,int col)
- {
- union REGS regs;
-
- regs.h.dh = row;
- regs.h.dl = col;
- regs.h.ah = 2;
- regs.h.bh = cur_page;
- int86(0x10,®s,®s);
- cur_row = row;
- cur_col = col;
- }
-
-
- /* scroll active page up.
- use to clear boxes on screen */
- void bios_scroll_up(
- int count,int sr,int sc,int er,int ec)
- {
- union REGS regs;
-
- regs.h.al = count;
- regs.h.ch = sr;
- regs.h.cl = sc;
- regs.h.dh = er;
- regs.h.dl = ec;
- regs.h.bh = cur_attr;
- regs.h.ah = 6;
- int86(0x10,®s,®s);
- }
-
- /* scroll active page down.
- good for clearing entire screen */
- void bios_scroll_dn(
- int count,int sr,int sc,int er,int ec)
- {
- union REGS regs;
-
- regs.h.al = count;
- regs.h.ch = sr;
- regs.h.cl = sc;
- regs.h.dh = er;
- regs.h.dl = ec;
- regs.h.bh = cur_attr;
- regs.h.ah = 7;
- int86(0x10,®s,®s);
- }
-
- /* return current video state */
- int bios_mode()
- {
- union REGS regs;
-
- regs.h.ah = 15;
- int86(0x10,®s,®s);
- cur_mode = regs.h.al;
- return(regs.h.al);
- }
-
- /* return current cursor position
- into global values */
- void bios_rc()
- {
- union REGS regs;
-
- regs.h.bh = cur_page;
- regs.h.ah = 3;
- int86(0x10,®s,®s);
- cur_row = regs.h.dh;
- cur_col = regs.h.dl;
- }
-
-
- /* print char (attribute at r/c unchanged)
- at current cursor position */
- void bios_putchar(char ch)
- {
- union REGS regs;
-
- regs.h.bh = cur_page;
- regs.x.cx =1;
- regs.h.al = ch;
- regs.h.ah = 0x0a;
- int86(0x10,®s,®s);
- }
-
- /* print char & attribute at cusor position */
- void bios_pchatt(char ch)
- {
- union REGS regs;
-
- regs.h.bh = cur_page;
- regs.h.bl = cur_attr;
- regs.x.cx = 1;
- regs.h.al = ch;
- regs.h.ah = 0x09;
- int86(0x10,®s,®s);
- }
-
- /* this function replaces puts()
- (but no linefeed on end)
- recognises LF,CR,BS and TAB
- Use sprintf() with this to simulate printf()
- (need large buffer too) */
- void bios_puts(char *str)
- {
- int i;
- bios_rc();
- while(*str)
- {
- if(*str == 10) /* do LF */
- {
- cur_col = 0;
- cur_row++;
- bios_move(cur_row,cur_col);
- str++;
- if(!*str)
- break;
- }
- if(*str == 8) /* do BS */
- {
- if(cur_col == 0)
- cur_row--;
- else
- cur_col--;
- bios_move(cur_row,cur_col);
- str++;
- if(!*str)
- break;
- }
- if(*str == 13) /* do CR */
- {
- cur_col = 0;
- bios_move(cur_row,cur_col);
- str++;
- if(!*str)
- break;
- }
- if(*str == 9) /* do TAB */
- {
- i = (1+(cur_col / 8)) *8;
- while(cur_col < i)
- {
- bios_pchatt(' ');
- cur_col++;
- bios_move(cur_row,cur_col);
- }
- str++;
- if(!*str)
- break;
- }
-
- bios_pchatt(*str);
- str++;
- cur_col++;
- bios_move(cur_row,cur_col);
- }
- }
-
- /* returns the char under the cursor */
- char bios_rdchar()
- {
- union REGS regs;
-
- regs.h.bh = cur_page;
- regs.h.ah = 8;
- int86(0x10,®s,®s);
- return((char)regs.h.al);
- }
-
- /* returns char AND attribute under cursor */
- int bios_rdchatt()
- {
- union REGS regs;
-
- regs.h.bh = cur_page;
- regs.h.ah = 8;
- int86(0x10,®s,®s);
- /* char is in AL, attribute is in AH */
- return((int)regs.x.ax);
- }
-
- /* this function was written by Andrew Binstock.
- The text of the function
- and the supporting artical can be found in
- the magazine: C Gazette, Summer 1989 issue.
- (v4 #1) p27.
- Only minor modifications have been made by me.
- */
- /* test to determine type of
- video adapter in the system */
- void vtest()
- {
- union REGS regs;
- unsigned char hold_a_byte;
- int i;
-
- /* identify VGA/MCGA/EGA */
- regs.h.ah = 0x1a;
- regs.h.al = 0;
- int86(0x10,®s,®s);
-
- /* true only for VGA, MCGA */
- if(regs.h.al == 0x1a)
- {
- if(regs.h.bl < 0x0a)
- vga =1;
- else
- mcga =1;
- color = 1;
- return;
- }
-
- /* next test for EGA */
- regs.h.ah = 0x12;
- regs.h.bl = 0x10;
- int86(0x10,®s,®s);
- if(regs.h.bl != 0x10) /* it's an EGA */
- {
- ega = 1;
-
- /* EGA can be color or B+W */
- if(regs.h.bh ==0)
- color = 1;
- else
- b_w = 1;
- return;
- }
-
- /* not any of the above,
- so it must be CGA or MONO (or HERC) */
-
- /* test for MONO by looking at the current mode */
- bios_mode();
-
- /* go to MONO test. CGA can't use mode 7 */
- if(cur_mode != 7)
- {
- /* test CGA by looking at the CGA registers */
- outp(0x3d4,0x0f); /* get value of reg 15 */
- hold_a_byte = inp(0x3d5); /* save it */
- outp(0x3d5,0x63); /* write an unlikely value */
- for(i=0;i< 100;i++) /* wait a bit */
- ;
- if(inp(0x3d5) == 0x63) /* read it back */
- {
- outp(0x3d5,hold_a_byte); /* restore value */
- cga = 1;
- color = 1;
- return;
- }
- else
- {
- outp(0x3d5,hold_a_byte);
- none = 1;
- color =1;
- return;
- }
- }
- /* not CGA, Test for MDA and HERC.
- Same test as CGA but to mono ports */
- outp(0x3b4,0xf);
- hold_a_byte = inp(0x3b5);
- outp(0x3b5,0x63);
- for(i=0;i<100;i++)
- ;
- if(inp(0x3b5) != 0x63)
- {
- outp(0x3b5,hold_a_byte);
- none = 1;
- b_w = 1;
- return;
- }
- outp(0x3b5,hold_a_byte);
- /* must be a MONO but is it a HERCULES????? */
- hold_a_byte = inp(0x3ba); /* check status port */
- hold_a_byte &= 0x80; /* isolate bit 7 */
- for(i=0; i< 1000; i++)
- {
- if(inp(0x3ba) & 0x80 != hold_a_byte)
- {
- /* if value changes, hercules is present */
- herc = 1;
- break;
- }
- }
- if(!herc)
- {
- /* must be just MDA */
- mono = 1;
- b_w = 1;
- return;
- }
-
- /* determine if the card is herc mono or color */
- hold_a_byte = inp(0x3ba);
- switch(hold_a_byte)
- {
- case 0x50: color = 1;
- break;
- case 0x00: b_w = 1;
- break;
- /* case 0x10: graphics plus card found */
- }
- }
-
-
-
-